#include <stdlib.h>
#include <stdio.h>

#include "od_def.h"
#include "od_trace.h"
#include "od_task.h"
#include "od_tube.h"
#include "od_os.h"
#include "od_msg.h"
#include "od_os_config.h"
#include "od_engine.h"
#include "od_sip_comn.h"
#include "od_sip_state_machine.h"


#define MODULE_NAME "sip Finite State Machine"
#define SIP_STATE_MACHINE_TSK_STACK_SIZE  (1024 * 1024)   /*线程栈资源大小*/
#define DATE_FMT "%Y-%m-%d %H:%M:%S"


typedef struct 
{
    TASK_COMMON_MEMBERS

    od_sip_ctx *ctx;    
}sip_state_machine_obj;

params_def sip_state_machine_dynamic_params_def[]=
{
    {OFFSET(od_sip_state_machine_dynamic_params, phone_status), PT_VAR_INT32 | PT_REAL_TIME, sizeof(int), 0, 0xFFFF},
    {OFFSET(od_sip_state_machine_dynamic_params, time_cnt),     PT_VAR_STR | PT_REAL_TIME, sizeof(char), 0, 128},
    {0, 0, 0, 0, 0}
};

const od_sip_state_machine_dynamic_params glb_sip_state_machine_dynamic_params_default = 
{
    PHONE_STATUS_AVAILABLE,     /*phone status*/
    "00:00:00"                  /*time_cnt*/
};


phone_status get_phone_status(void *h)
{
    sip_state_machine_obj *obj = h;
    od_sip_state_machine_dynamic_params *param = obj->params;
    
    OD_SIP_ASSERT_RETURN(obj, OD_ERROR);
    return param->phone_status;
}

void set_phone_status(void *h, phone_status value)
{
    sip_state_machine_obj * obj = h;
    od_sip_state_machine_dynamic_params *param = obj->params;
    OD_SIP_ASSERT(obj);

    od_mutex_lock(&obj->mux);
    param->phone_status = value;
    od_mutex_unlock(&obj->mux);
}


static int sip_state_machine_start_stop(sip_state_machine_obj *obj)
{
    od_sip_state_machine_dynamic_params *params = obj->params;

    obj->ctx = od_sip_lib_start();
    OD_SIP_ASSERT_RETURN(obj->ctx, OD_ERROR);
    params->phone_status = PHONE_STATUS_AVAILABLE;

    return OD_OK;
}

static void sip_state_machine_start_stop_delete(sip_state_machine_obj * obj)
{
    od_sip_lib_stop();
}

static int sip_state_machine_process(sip_state_machine_obj *obj)
{
    od_sip_state_machine_dynamic_params *param = obj->params;

    switch(param->phone_status)
    {
        case PHONE_STATUS_UNSUPPORT_MEDIA_TYPE:
        case PHONE_STATUS_REMOTE_BUSY:
        case PHONE_STATUS_MEDIA_ERR:
        case PHONE_STATUS_HANG:
        case PHONE_STATUS_LOCAL_ERR:
        case PHONE_STATUS_CALL_REQUESTFAILURE:
        case PHONE_STATUS_CANCEL:
        case PHONE_STATUS_NOT_FOUND:
        case PHONE_STATUS_REQUEST_TERMINATED:
        case PHONE_STATUS_RELEASE:
            set_phone_status(obj, PHONE_STATUS_AVAILABLE);
            break;
            
        case PHONE_STATUS_DIAL:
        case PHONE_STATUS_REMOTE_RINGING:
        case PHONE_STATUS_PROCEEDING:
            break;
        
        case PHONE_STATUS_CONVERSATION:
            break;
            
        case PHONE_STATUS_NEW_CALL_COMING:
        case PHONE_STATUS_LOCAL_RINGING:
        case PHONE_STATUS_SEND_200OK:
            break;
        
        case PHONE_STATUS_AVAILABLE:
            break;
        default:
            break;
    }

    od_msleep(50);
    
    return OD_OK;
}


od_sip_state_machine_handle od_sip_state_machine_create(od_sip_state_machine_static_params *static_params,
                                                           od_sip_state_machine_dynamic_params *dynamic_params)
{
    sip_state_machine_obj *obj = NULL;
    od_sip_state_machine_dynamic_params *params = NULL;

    OD_SIP_ASSERT_RETURN(static_params, NULL);

    /* create and initialize task object */
    obj = od_task_create((char *)static_params->task_name, sizeof(sip_state_machine_obj));
    if(obj == NULL)
    {
        RPTERR(" create NULL pointer");
        return NULL;
    }

    obj->tab = sip_state_machine_dynamic_params_def;
    obj->params_nums = sizeof(sip_state_machine_dynamic_params_def) / (sizeof(params_def)) - 1;
    
    params = od_calloc(1, sizeof(od_sip_state_machine_dynamic_params));
    OD_SIP_ASSERT_RETURN(params, NULL);

    if(NULL == dynamic_params)
    {
        memcpy(params, &glb_sip_state_machine_dynamic_params_default, sizeof(od_sip_state_machine_dynamic_params));
    }
    else
    {
        memcpy(params, dynamic_params, sizeof(od_sip_state_machine_dynamic_params));
    }

    obj->params = (void *)params;
 
    obj->stack_size = SIP_STATE_MACHINE_TSK_STACK_SIZE;
    obj->pf_start_stop  = (void *)sip_state_machine_start_stop;
    obj->pf_malloc_free = NULL;
    obj->pf_rt_set = NULL;
    obj->pf_process     = (void *)sip_state_machine_process;
    obj->pf_malloc_free_delete = NULL;
    obj->pf_start_stop_delete = (void *)sip_state_machine_start_stop_delete;

    RPTDBG("create success");
    return (od_sip_state_machine_handle)obj;

/************************************************************************/
}




/*_*/

